package com.ihr360.payroll.controller.staff;


import com.google.common.collect.Lists;
import com.ihr360.commons.entity.AuthUserInfo;
import com.ihr360.commons.lang.CollectionUtils;
import com.ihr360.commons.vo.ResultInfo;
import com.ihr360.entity.StaffBankSalaryEntity;
import com.ihr360.excel.vo.ImportRequest;
import com.ihr360.maven.plugin.ModuleCodeStore;
import com.ihr360.maven.plugin.annotation.FunctionDefinition;
import com.ihr360.maven.plugin.annotation.ModuleDefinition;
import com.ihr360.payroll.config.system.SystemSalaryFieldEntity;
import com.ihr360.payroll.entity.staff.StaffSalaryEntity;
import com.ihr360.payroll.entity.staff.StaffSalaryProfileEntity;
import com.ihr360.payroll.request.StaffPayrollInfoRequest;
import com.ihr360.payroll.request.StaffPayrollInfoTimelineRequest;
import com.ihr360.payroll.request.StaffPayrollInfosRequest;
import com.ihr360.payroll.request.StaffSalaryProfileSearchBody;
import com.ihr360.payroll.response.StaffPayrollInfoResponse;
import com.ihr360.payroll.response.StaffPayrollInfoTimelineResponse;
import com.ihr360.payroll.service.salaryfield.SystemSalaryFieldService;
import com.ihr360.payroll.service.staff.StaffPayrollInfoJournalService;
import com.ihr360.payroll.service.staff.StaffPayrollInfoService;
import com.ihr360.shared.advice.response.DisableResponseAdvice;
import com.ihr360.validation.annonation.EnableValidation;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.MediaType;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.net.URLEncoder;
import java.util.List;
import java.util.stream.Collectors;


@Api(value = "员工薪资相关接口")
@RestController
@RequestMapping("/staffPayrollInfoes")
@ModuleDefinition(mainModuleCode = ModuleCodeStore.Module.SALARY_CODE, mainModuleName = ModuleCodeStore.Module.SALARY_NAME,
        subModuleCode = ModuleCodeStore.Module.Salary.STAFF_PAY_ROLLINFO_CODE, subModuleName = ModuleCodeStore.Module.Salary.STAFF_PAY_ROLLINFO_NAME)
public class StaffSalaryProfileController {

    @Autowired
    private StaffPayrollInfoService staffPayrollInfoService;

    @Autowired
    private StaffPayrollInfoJournalService staffPayrollInfoJournalService;

    @Autowired
    private SystemSalaryFieldService systemSalaryFieldService;

//    @Override
//    public SimpleRestService<StaffSalaryProfile, String> getSimpleRestService() {
//        return staffPayrollInfoService;
//    }


    @ApiOperation(value = "修改员工薪资档案薪资项数据")
    @PostMapping(value = "/salaryProfile/wrapper/update", produces = MediaType.APPLICATION_JSON_UTF8_VALUE)
    @EnableValidation
    @FunctionDefinition(functionName = "修改员工薪资档案薪资项数据", functionCode = ModuleCodeStore.Function.EDIT)
    public Boolean updateSalaryfile(@RequestBody StaffPayrollInfosRequest staffpayrollInfos) {
        return staffPayrollInfoService.adjustSalaryProfileWrapper(staffpayrollInfos);
    }

    @ApiOperation(value = "异动调整员工薪资档案薪资项数据,用于数据修复")
    @PostMapping(value = "/salaryProfile/abnormallity/adjust", produces = MediaType.APPLICATION_JSON_UTF8_VALUE)
    @FunctionDefinition(functionName = "异动调整员工薪资档案薪资项数据,用于数据修复", functionCode = ModuleCodeStore.Function.EDIT, isPublic = true)
    public ResultInfo abnormalityAdjustProfile(@RequestBody StaffPayrollInfoRequest staffpayrollInfos) {
        return staffPayrollInfoService.abnormalityAdjustProfileWrapper(staffpayrollInfos);
    }

    @ApiOperation(value = "获取已进行过薪资转正数据迁移的员工,用于数据初始化")
    @GetMapping(value = "/staffIds/probationReview", produces = MediaType.APPLICATION_JSON_UTF8_VALUE)
    @DisableResponseAdvice
    @FunctionDefinition(functionName = "获取已进行过薪资转正数据迁移的员工,用于数据初始化", functionCode = ModuleCodeStore.Function.EDIT, isPublic = true)
    public List<String> probationReviewStaffIdsFromIrs(@RequestParam(name = "companyId") String companyId) {
        return staffPayrollInfoService.probationReviewStaffIdsFromIrs(companyId);
    }


    @ApiOperation(value = "获取公司存在员工薪资档案数据的所有员工")
    @GetMapping(value = "/staffIds", produces = MediaType.APPLICATION_JSON_UTF8_VALUE)
    @DisableResponseAdvice
    @FunctionDefinition(functionName = "公司存在员工薪资档案数据的所有员工", functionCode = ModuleCodeStore.Function.VIEW)
    public List<String> getStaffIdsForExistsSalaryProfile(@RequestParam(name = "companyId") String companyId) {
        return staffPayrollInfoService.getStaffIdsForExistsSalaryProfile(companyId);
    }

    @ApiOperation(value = "保存员工薪资薪资档案数据")
    @PostMapping(value = "/save", produces = MediaType.APPLICATION_JSON_UTF8_VALUE)
    @DisableResponseAdvice
    @FunctionDefinition(functionName = "保存员工薪资薪资档案数据", functionCode = ModuleCodeStore.Function.EDIT)
    public ResultInfo saveStaffSalaryProfile(@RequestBody List<StaffSalaryProfileEntity> toSave) {

        List<String> staffids = Lists.newArrayList();
        if (CollectionUtils.isNotEmpty(toSave)) {
            staffids = toSave.stream().map(s -> s.getStaff().getId()).collect(Collectors.toList());
        }
        staffPayrollInfoService.save(staffids, toSave);
        return new ResultInfo.Builder().success();
    }


    @ApiOperation(value = "获取当前生效薪资档案")
    @PostMapping(value = "/list/currentEffective", produces = MediaType.APPLICATION_JSON_UTF8_VALUE)
    @DisableResponseAdvice
    @FunctionDefinition(functionName = "获取当前生效薪资档案", functionCode = ModuleCodeStore.Function.EDIT, isPublic = true)
    public StaffPayrollInfoResponse getCurrentEffective(@RequestBody StaffSalaryProfileSearchBody param) {
        return staffPayrollInfoService.getCurrentEffectiveData(param.getAuthStaffIds(), param);
    }

    @ApiOperation(value = "获取当前生效薪资档案之后的薪资档案")
    @GetMapping(value = "/list/afterCurrent/{staffId}", produces = MediaType.APPLICATION_JSON_UTF8_VALUE)
    @FunctionDefinition(functionName = "获取当前生效薪资档案之后的薪资档案", functionCode = ModuleCodeStore.Function.VIEW)
    public List<StaffSalaryProfileEntity> getAfterCurrentDatas(@PathVariable(name = "staffId") String staffId) {
        return staffPayrollInfoService.getAfterCurrentDatas(Lists.newArrayList(staffId));
    }

    @ApiOperation(value = "根据staffId获取员工所有薪资档案")
    @GetMapping(value = "/list/{staffId}", produces = MediaType.APPLICATION_JSON_UTF8_VALUE)
    @FunctionDefinition(functionName = "获取员工所有薪资档案", functionCode = ModuleCodeStore.Function.VIEW)
    public List<StaffSalaryProfileEntity> getStaffPayrollInfos(@PathVariable(name = "staffId") String staffId) {
        return staffPayrollInfoService.getStaffPayrollInfos(Lists.newArrayList(staffId));
    }

    @ApiOperation(value = "获取当前生效薪资档案之后的薪资档案")
    @GetMapping(value = "/list", produces = MediaType.APPLICATION_JSON_UTF8_VALUE)
    @DisableResponseAdvice
    @FunctionDefinition(functionName = "根据companyId和staffId获取员工所有薪资档案", functionCode = ModuleCodeStore.Function.VIEW)
    public List<StaffSalaryProfileEntity> getStaffPayrollInfos(@RequestParam(name = "staffId") String staffId, @RequestParam(name = "companyId") String companyId) {
        return staffPayrollInfoService.getStaffPayrollInfos(Lists.newArrayList(staffId), companyId);
    }

    @ApiOperation(value = "获取当前生效薪资档案前后的记录")
    @PostMapping(value = "/list/nearestTimeline", produces = MediaType.APPLICATION_JSON_UTF8_VALUE)
    @FunctionDefinition(functionName = "获取当前生效薪资档案前后的记录", functionCode = ModuleCodeStore.Function.VIEW)
    public StaffPayrollInfoTimelineResponse getPayrollInfoNearestTimeline(@RequestBody StaffPayrollInfoTimelineRequest rquest) {
        return staffPayrollInfoJournalService.getPayrollInfoNearestTimes(rquest.getStaffId(), rquest.getCode(), rquest.getValue(), rquest.getChangeType());
    }

    @ApiOperation(value = "查询员工银行卡及工资信息（花名册页面使用）")
    @GetMapping(value = "/staffSalaryInfo", produces = MediaType.APPLICATION_JSON_UTF8_VALUE)
    @FunctionDefinition(functionName = "查询员工银行卡及工资信息", functionCode = ModuleCodeStore.Function.VIEW)
    public StaffSalaryEntity getStaffSalaryInfo(AuthUserInfo userInfo, @RequestParam String staffId) {
        return staffPayrollInfoService.getStaffSalaryInfo(Lists.newArrayList(staffId), userInfo.getCompanyId());
    }

    @ApiOperation(value = "保存员工薪资信息（花名册页面使用）")
    @PostMapping(value = "/staffSalaryInfo/save", produces = MediaType.APPLICATION_JSON_UTF8_VALUE)
    @FunctionDefinition(functionName = "保存员工薪资信息（花名册页面使用）", functionCode = ModuleCodeStore.Function.VIEW)
    public void saveStaffSalaryInfo(@RequestBody StaffSalaryEntity entity) {

        staffPayrollInfoService.saveStaffSalaryInfo(Lists.newArrayList(entity.getStaffId()), entity);
    }

    /**
     * 银行卡信息数据修复使用
     */
    @PostMapping(value = "/saveAllStaffSalaryInfo", produces = MediaType.APPLICATION_JSON_UTF8_VALUE)
    @FunctionDefinition(functionName = "银行卡信息数据修复使用", functionCode = ModuleCodeStore.Function.EDIT, isPublic = true)
    public void saveAllStaffSalaryInfo(@RequestParam String companyId, @RequestBody List<StaffBankSalaryEntity> staffBankSalaryEntityList) {
        List<String> staffIds = Lists.newArrayList();
        if (CollectionUtils.isNotEmpty(staffBankSalaryEntityList)) {
            staffIds = staffBankSalaryEntityList.stream().map(StaffBankSalaryEntity::getStaffId).collect(Collectors.toList());
        }
        staffPayrollInfoService.saveAllStaffSalaryInfo(staffIds, companyId, staffBankSalaryEntityList);
    }

    @FunctionDefinition(functionName = "下载员工薪资导入模板", functionCode = ModuleCodeStore.Function.IMPORT)
    @RequestMapping(value = "/template", method = RequestMethod.GET, produces = MediaType.APPLICATION_JSON_VALUE)
    public void downloadTemplate(HttpServletResponse response) throws IOException {
        response.setHeader("x-filename", URLEncoder.encode("员工薪资.xls", "UTF-8"));
        staffPayrollInfoService.downloadTemplate(response.getOutputStream());
    }

    @FunctionDefinition(functionName = "导入员工薪资数据", functionCode = ModuleCodeStore.Function.IMPORT)
    @RequestMapping(value = "/upload", method = RequestMethod.POST, produces = MediaType.APPLICATION_JSON_VALUE)
    public ResultInfo upload(@RequestBody ImportRequest importRequest) throws IOException {
        staffPayrollInfoService.importSalaryProfile(importRequest);
        return new ResultInfo.Builder<>().success();
    }

    @ApiOperation(value = "根据类型获取元数据")
    @GetMapping(value = "/list/showInStaffSalary", produces = MediaType.APPLICATION_JSON_UTF8_VALUE)
    @FunctionDefinition(functionName = "获取可以添加到员工薪资的系统薪资项目", functionCode = ModuleCodeStore.Function.SALARY_FIELD_MANAGE)
    public List<SystemSalaryFieldEntity> listCanShowInStaffSalary() {
        return systemSalaryFieldService.listCanShowInStaffSalary();
    }


}
